package com.rundatop.wx.util;

import java.math.BigDecimal;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.rundatop.wx.dto.PointEntity;
import com.rundatop.wx.dto.elements;
import com.sun.prism.impl.Disposer.Record;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;


/**
 * 一个低端小气没档次的程序狗 JavaDog
 * blog.javadog.net
 *
 * @BelongsProject: springboot-wexin
 * @BelongsPackage: net.javadog.springbootwexin.utils
 * @Author: hdx
 * @CreateTime: 2020-02-14 21:19
 * @Description: 微信工具类
 */
@Component
public class WxUtil {
	protected static String MapKey;
    protected static String AppId;
    protected static String AppSecret;
    protected static String JssdkAccesstokenUrl;
    protected static String JssdkGetticketUrl;
    protected static String MapReverseGeocoderUrl;
    protected static String MapDistanceUrl;
    
    public static String getMapKey() {
		return MapKey;
	}
    
    public static String getAppId() {
		return AppId;
	}

	public static String getAppSecret() {
		return AppSecret;
	}

	public static String getJssdkAccesstokenUrl() {
		return JssdkAccesstokenUrl;
	}

	public static String getJssdkGetticketUrl() {
		return JssdkGetticketUrl;
	}

	@Value("${wx.app-id}")
    public void setAppId(String appId) {
        AppId = appId;
    }
	
	@Value("${wx.map-key}")
    public void setMapKey(String mapKey) {
		MapKey = mapKey;
    }
	

    @Value("${wx.app-secret}")
    public void setAppSecret(String appSecret) {
        AppSecret = appSecret;
    }

    @Value("${wx.jssdk_accesstoken_url}")
    public void setJssdkAccesstokenUrl(String jssdkAccesstokenUrl) {
        JssdkAccesstokenUrl = jssdkAccesstokenUrl;
    }
    
    @Value("${wx.map_reverseGeocoder_url}")
    public void setMapReverseGeocoderUrl(String reverseGeocoder) {
        MapReverseGeocoderUrl = reverseGeocoder;
    }

    @Value("${wx.jssdk_getticket_url}")
    public void setJssdkGetticketUrl(String jssdkGetticketUrl) {
        JssdkGetticketUrl = jssdkGetticketUrl;
    }
    
    @Value("${wx.map_distance_url}")
    public void setMapDistanceUrl(String distance) {
        MapDistanceUrl = distance;
    }

    /**
    *@Author: hdx
    *@CreateTime: 21:31 2020/2/14
    *@param:  * @param null
    *@Description:
    
    */
    public static String getJSSDKAccessToken() {
        String token = null;
        String url = JssdkAccesstokenUrl.replaceAll("APPID",
                AppId).replaceAll("APPSECRET",
                AppSecret);
        String json = postRequestForWeiXinService(url);
        System.out.println("getJSSDKAccessToken:"+json);
        Map map = jsonToMap(json);
        if (map != null) {
            token = (String) map.get("access_token");
        }
        return token;
    }
    
    public static String getMapReverseGeocoderUrl(String location) {
        String token = null;
        String mapurl = MapReverseGeocoderUrl.replaceAll("KEY",
                MapKey).replaceAll("LOC",location);
        
        String json = postRequestForWeiXinService(mapurl);
        String data=HttpRequestUtil.sendGet("https://apis.map.qq.com/ws/geocoder/v1/", "key="+MapKey+"&location="+location);
        Map map = jsonToMap(json);
        if (map != null) {
        	System.out.println(map);
            token = (String) map.get("access_token");
        }
        return token;
    }
    
    public static Double getDistance(String location, String storeLoc) {
//        String token = null;
////        String mapurl = MapDistanceUrl.replaceAll("KEY",
////                MapKey).replaceAll("LOC",location).replaceAll("LOC1",storeLoc);
////        String mapurl = "https://apis.map.qq.com/ws/distance/v1?mode=walking&from="+location+"&to="+storeLoc+"&key="+MapKey;
////        String url = "https://apis.map.qq.com/ws/distance/v1";
//        String param = "mode=walking&from="+location+"&to="+storeLoc+"&key="+MapKey;
////        String json = postRequestForWeiXinService(mapurl);
//        String data=HttpRequestUtil.sendGet("https://apis.map.qq.com/ws/distance/v1",param);
//        System.out.println(data);
//        Map map = jsonToMap(data);
//        System.out.println(map+"!!!!!!!!");
//        if (map.get("message").equals("query ok")) {
//        	Map result = (Map) map.get("result");
//        	List<elements> elements = (List<elements>) result.get("elements");
//        	Map e = (Map) elements.get(0);
//        	Double distance = (Double) e.get("distance");
//			return distance;
//		}
//        return 0.0;
    	double storeLnt = 0.0;
    	double storeLat = 0.0;
    	double myLnt = 0.0;
    	double myLat = 0.0;
    	if (StringUtils.isNotBlank(storeLoc) && StringUtils.isNotBlank(location)) {
			String[] stores = storeLoc.split(",");
			String[] mys = location.split(",");
			storeLat = Double.valueOf(stores[0]);
			storeLnt = Double.valueOf(stores[1]);
			myLat = Double.valueOf(mys[0]);
			myLnt = Double.valueOf(mys[1]);
		}
    	PointEntity pointA = new PointEntity(myLnt, myLat);
        PointEntity pointB = new PointEntity(storeLnt, storeLat);
        double len = distanceToPoint(pointA,pointB);
        BigDecimal b = new BigDecimal(len/1000);  
        len = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();  
        return len;
    }
    
    public static Map<String, Object> getPoi(String location) {
        String token = null;
//        String mapurl = MapDistanceUrl.replaceAll("KEY",
//                MapKey).replaceAll("LOC",location).replaceAll("LOC1",storeLoc);
//        String mapurl = "https://apis.map.qq.com/ws/distance/v1?mode=walking&from="+location+"&to="+storeLoc+"&key="+MapKey;
//        String url = "https://apis.map.qq.com/ws/distance/v1";
        String param = "location="+location+"&key="+MapKey;
//        String json = postRequestForWeiXinService(mapurl);
        String data=HttpRequestUtil.sendGet("https://apis.map.qq.com/ws/geocoder/v1/",param);
        System.out.println(data);
        Map map = jsonToMap(data);
        System.out.println(map+"!!!!!!!!");
        if (map.get("message").equals("query ok")) {
        	Map result = (Map) map.get("result");
        	Map<String, Object> adInfo = (Map<String, Object>) result.get("ad_info");
			return adInfo;
		}
        return null;
    }
    
    public static double distanceToPoint(PointEntity pointA, PointEntity pointB){
        //jts提供的几何要素工厂类
        GeometryFactory geometryFactory = new GeometryFactory();

        //火星坐标(gcj02)转GPS坐标(WGS84)
        double[] wgsPntA = CoordinateUtil.gcj02_To_Wgs84(pointA.x,pointA.y);
        double[] wgsPntB = CoordinateUtil.gcj02_To_Wgs84(pointB.x,pointB.y);

        //WGS84->高斯6度分带投影
        double[] gaussPntA = CoordinateUtil.wgs84_To_Gauss6(wgsPntA[0],wgsPntA[1]);
        double[] gaussPntB = CoordinateUtil.wgs84_To_Gauss6(wgsPntB[0],wgsPntB[1]);

        //通过几何要素工厂得到point实体
        Point pntA = geometryFactory.createPoint(new Coordinate(gaussPntA[0], gaussPntA[1]));
        Point pntB = geometryFactory.createPoint(new Coordinate(gaussPntB[0], gaussPntB[1]));
        // 两点距离
        return pntA.distance(pntB);
    }
    
    public static void main(String[] args) {
		WxUtil e = new WxUtil();
//		119.13279 36.70864
//		36.705885,119.187824
//		36.426926,119.228545
//		36.706226,119.176658
		PointEntity pointA = new PointEntity(119.187824, 36.705885);
        PointEntity pointB = new PointEntity(119.176658, 36.706226);
        double len = distanceToPoint(pointA,pointB);
        System.out.println(len);
    }

    /**
    *@Author: hdx
    *@CreateTime: 21:40 2020/2/14
    *@param:  * @param null
    *@Description: 根据accessToken获取JssdkGetticket

    */
    public static String getJssdkGetticket(String accessToken) {
        String url = JssdkGetticketUrl.replaceAll("ACCESS_TOKEN", accessToken);
        String json = postRequestForWeiXinService(url);
        Map map = jsonToMap(json);
        String jsapi_ticket = null;
        if (map != null) {
            jsapi_ticket = (String) map.get("ticket");
        }
        return jsapi_ticket;
    }

    /**
    *@Author: hdx
    *@CreateTime: 21:41 2020/2/14
    *@param:ticket 根据accessToken生成的JssdkGetticket
    *@param:timestamp 支付签名时间戳，注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
    *@param:nonceStr 随机字符串
    *@param:url 当前网页的URL
    *@Description: 构建分享链接的签名

    */
    public static String buildJSSDKSignature(String ticket,String timestamp,String nonceStr ,String url) throws Exception {
        String orderedString = "jsapi_ticket=" + ticket
                + "&noncestr=" + nonceStr + "&timestamp=" + timestamp
                + "&url=" + url;
        System.out.println(orderedString);
        return sha1(orderedString);
    }

    /**
     * sha1 加密JSSDK微信配置参数获取签名。
     *
     * @return
     */
    public static String sha1(String orderedString) throws Exception {
        String ciphertext = null;
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        byte[] digest = md.digest(orderedString.getBytes());
        ciphertext = byteToStr(digest);
        return ciphertext.toLowerCase();
    }
    /**
     * 将字节数组转换为十六进制字符串
     *
     * @param byteArray
     * @return
     */
    private static String byteToStr(byte[] byteArray) {
        String strDigest = "";
        for (int i = 0; i < byteArray.length; i++) {
            strDigest += byteToHexStr(byteArray[i]);
        }
        return strDigest;
    }
    /**
     * 将字节转换为十六进制字符串
     *
     * @param mByte
     * @return
     */
    private static String byteToHexStr(byte mByte) {
        char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        char[] tempArr = new char[2];
        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
        tempArr[1] = Digit[mByte & 0X0F];

        String s = new String(tempArr);
        return s;
    }
    /**
    *@Author: hdx
    *@CreateTime: 21:49 2020/2/14
    *@param:  map
    *@Description:  mapToJson

    */
    public static String mapToJson(Map map){
        Gson gson = new Gson();
        String json = gson.toJson(map);
        return json;
    }

    /**
    *@Author: hdx
    *@CreateTime: 21:37 2020/2/14
    *@param:  json
    *@Description: jsonToMap

    */
    private static Map jsonToMap(String json) {
        Gson gons = new Gson();
        Map map = gons.fromJson(json, new TypeToken<Map>(){}.getType());
        return map;
    }

    /**
    *@Author: hdx
    *@CreateTime: 21:36 2020/2/14
    *@param:  * @param null
    *@Description: 调取微信接口

    */
    private static String postRequestForWeiXinService(String getAccessTokenUrl) {
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> postForEntity = restTemplate.postForEntity(getAccessTokenUrl, null, String.class);
        String json = postForEntity.getBody();
        return json;
    }

}
